<template>
  <div class="map-container">
    <!-- 地图 -->
    <div id="map" ref="map"></div>
    <!-- 四边遮挡 -->
    <div
      style="position: absolute;left: 0;top: 0;width: 100%;height: 80px;background: linear-gradient(180deg, #000 0%, #000 20%, transparent 100%);z-index: 102;pointer-events: none;">
    </div>
    <div
      style="position: absolute;left: 0;top: 0;width: 80px;height: 100%;background: linear-gradient(90deg, #000 0%, #000 20%, transparent 100%);z-index: 102;pointer-events: none;">
    </div>
    <div
      style="position: absolute;right: 0;bottom: 0;width: 100%;height: 80px;background: linear-gradient(0deg, #000 0%, #000 20%, transparent 100%);z-index: 102;pointer-events: none;">
    </div>
    <div
      style="position: absolute;right: 0;top: 0;width: 80px;height: 100%;background: linear-gradient(-90deg, #000 0%, #000 20%, transparent 100%);z-index: 102;pointer-events: none;">
    </div>
    <!-- 大屏导航栏 -->
    <NavBar />
    <!-- 大屏两边展示 -->
    <keep-alive>
      <router-view />
    </keep-alive>

    <div>
      <button @click="isDebugPanel = !isDebugPanel"
        style="background-color: aliceblue;color: #333;position:fixed;right:.625rem;;top:30px;z-index: 10000;">Debug</button>
      <div v-show="isDebugPanel"
        style="position:fixed;right:10px;;top:30px;z-index:9999;color:#333;font-size: 12px;width:auto;background-color:#fff;padding: 5px;padding-left: 30px;">
        <button @click="showOrHidePipeline()" style="position: relative;left: -25px;font-size: 14px;margin-right: 5px;">管道网</button>
        <button @click="createCityFullRiver()" style="position: relative;left: -25px;font-size: 14px;margin-right: 5px;">全市湖泊</button>
        <button @click="createWaterRoute()" style="position: relative;left: -25px;font-size: 14px;margin-right: 5px;">全市水路</button>
        <!-- <button @click="switchBaseMap()" style="position: relative;left: -25px;font-size: 14px;margin-right: 5px;">暗色/亮色</button> -->

        <div>
          <div style="position: relative;left: -25px;font-size: 14px;">2.建筑物配色</div>
          <div>u_colorBottom：{{ u_colorBottom }} <input type="color" v-model="u_colorBottom" @change="v_change"></div>
          <div>u_colorTop：{{ u_colorTop }} <input type="color" v-model="u_colorTop" @change="v_change"></div>
          <div>u_bottomToplerp：<input type="number" v-model="u_bottomToplerp" @change="v_change"></div>
          <div>u_baseHeight：<input type="number" v-model="u_baseHeight" @change="v_change"></div>
          <div>u_heightRange：<input type="number" v-model="u_heightRange" @change="v_change"></div>
          <div>u_glowRange：<input type="number" v-model="u_glowRange" @change="v_change"></div>
        </div>

        <div>
          <div style="position: relative;left: -25px;font-size: 14px;">3.绘制</div>
          <button @click="measureSurfaceLength()">绘制面</button>
          <button @click="drawPolygon()">框选POI (开始/结束)</button>
        </div>

        <div>
          <button @click="clearCache()" style="position: relative;left: -25px;font-size: 14px;margin-right: 5px;background-color:darksalmon;">清除缓存</button>
        </div>

        <div v-show="true">
          <div style="position: relative;left: -25px;font-size: 14px;">3.编辑树</div>
          <div class="tree-container">
            <div class="tree-item" :class="{ active: treeActive == 1 }"
              @click="treeActive = 1; drawDebugLayerStopDraw(); treeDebugDraw(1);"
              :style="{ 'background-image': `url(${basePathUrl + 'models/tree_sample.png'})`, 'background-position': `${-34 * 0}px 0px`, }">
            </div>
            <div class="tree-item" :class="{ active: treeActive == 2 }"
              @click="treeActive = 2; drawDebugLayerStopDraw(); treeDebugDraw(1);"
              :style="{ 'background-image': `url(${basePathUrl + 'models/tree_sample.png'})`, 'background-position': `${-34 * 1}px 0px`, }">
            </div>
            <div class="tree-item" :class="{ active: treeActive == 3 }"
              @click="treeActive = 3; drawDebugLayerStopDraw(); treeDebugDraw(1);"
              :style="{ 'background-image': `url(${basePathUrl + 'models/tree_sample.png'})`, 'background-position': `${-34 * 2}px 0px`, }">
            </div>
            <div class="tree-item" :class="{ active: treeActive == 4 }"
              @click="treeActive = 4; drawDebugLayerStopDraw(); treeDebugDraw(1);"
              :style="{ 'background-image': `url(${basePathUrl + 'models/tree_sample.png'})`, 'background-position': `${-34 * 3}px 0px`, }">
            </div>
            <div class="tree-item" :class="{ active: treeActive == 5 }"
              @click="treeActive = 5; drawDebugLayerStopDraw(); treeDebugDraw(1);"
              :style="{ 'background-image': `url(${basePathUrl + 'models/tree_sample.png'})`, 'background-position': `${-34 * 4}px 0px`, }">
            </div>
            <div class="tree-item" :class="{ active: treeActive == 6 }"
              @click="treeActive = 6; drawDebugLayerStopDraw(); treeDebugDraw(1);"
              :style="{ 'background-image': `url(${basePathUrl + 'models/tree_sample.png'})`, 'background-position': `${-34 * 5}px 0px`, }">
            </div>
            <div class="tree-item" :class="{ active: treeActive == null }" @click="treeActive = null; drawDebugLayerStopDraw(); treeDebugDraw('lu');" style="background-color: #333;color: #fff;">路网</div>

          </div>
          <button @click="treeDebugDraw(2)">完成</button>
          <button @click="treeDebugDraw(3)">控制台打印</button>
        </div>

      </div>
    </div>

  </div>
</template>

<script>
var dayjs = require('dayjs')
import HolographicMaterial from '@/components/Holographic'
import ThreeLayer from '@/components/ThreeLayer'
import NavBar from './BigScreen/NavBar/Index'
import { BSEvent } from './Consts'
import Hls from 'hls.js'
import DPlayer from 'dplayer'
import * as echarts from 'echarts'
import 'echarts-liquidfill'
import 'mars3d-echarts'
import 'mars3d/dist/mars3d.css'
import '@/style/mars3dCover.scss'
import '@/style/divGraphic.scss'
import * as mars3d from 'mars3d'
HolographicMaterial.ShowLog();
const Cesium = mars3d.Cesium;
window.Cesium = Cesium;
const basePathUrl = window.basePathUrl;
const CesiumNetworkPlug = require("@/assets/js/CesiumNetworkPlug.js")
var map, defaultContextmenuItems, outlineEffect, underground, terrainPlanClip, drawDebugPolygon, drawDebugGraphicSelected = [];
//图层
var baseLayer, mainLayer, drawDebugLayer;
//图形组
var groups = {};
export default {
  name: 'Map',
  components: { NavBar, },
  data() {
    return {
      //经纬度 -> 笛卡尔空间直角坐标
      // var cartesian3 = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
      //笛卡尔空间直角坐标 -> 经纬度
      // var point = mars3d.LngLatPoint.fromCartesian(cartesian3);
      //笛卡尔空间直角坐标 -> 屏幕坐标
      // var windowPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(map.scene, cartesian3);

      u_colorBottom: "#0a1029",
      u_colorTop: "#171b4f",
      u_bottomToplerp: 900,
      u_baseHeight: 510,
      u_heightRange: 15,
      u_glowRange: 500,

      bsTimer: null, //大屏更新定时器
      basePathUrl: basePathUrl,
      baseApiUrl: "http://xxxx",
      configUrl: basePathUrl + 'config/config.json',
      isShowPipeline: false,
      treeActive: 1,
      isDebugPanel: false,



    }
  },
  mounted() {
    this.window = window;
    this.$nextTick(() => {
      //大屏
      this.create_BS_Timer_Listener();
      //地图
      mars3d.Util.fetchJson({ url: this.configUrl }).then((data) => {
        this.initMars3d({ ...data.map3d })
      })
    })
  },
  beforeDestroy() {
    if (this.map) {
      this.map.destroy()
      delete this.map
    }
    if (this.bsTimer) {
      clearInterval(this.bsTimer)
      this.bsTimer = null
    }
  },

  methods: {
    v_change() {
      var t = map.getLayer("deyang_city1", "id")
      t.customShader.uniforms.u_colorBottom.value = Cesium.Color.fromCssColorString(this.u_colorBottom)
      t.customShader.uniforms.u_colorTop.value = Cesium.Color.fromCssColorString(this.u_colorTop)
      t.customShader.uniforms.u_bottomToplerp.value = this.u_bottomToplerp
      t.customShader.uniforms.u_baseHeight.value = this.u_baseHeight
      t.customShader.uniforms.u_heightRange.value = this.u_heightRange
      t.customShader.uniforms.u_glowRange.value = this.u_glowRange

    },

    //大屏---------------------
    create_BS_Timer_Listener() {
      //定时器
      this.bsTimer = setInterval(() => {
        this.$bus.$emit(BSEvent.AllRefresh)
      }, 1000 * 30);

      /**
       * 监听交互
       */
      this.$bus.$on("", () => {

      })
    },

    initMars3d(mapOptions) {
      if (this.map) this.map.destroy();
      //覆盖config.json
      var mapOptions2 = mars3d.Util.merge(mapOptions, {
        terrain: { show: true },
        control: {
          clockAnimate: false,
          timeline: false
        }
      })
      //实例化
      map = this.map = new mars3d.Map('map', mapOptions2)
      //右键旋转
      map.changeMouseModel(true)
      // map.viewer.clock.currentTime = Cesium.JulianDate.fromIso8601("2024-08-05T14:30:00Z");
      //固定光线
      map.fixedLight = true
      //深度检测
      map.scene.globe.depthTestAgainstTerrain = false
      //交换左右键
      map.scene.screenSpaceCameraController.tiltEventTypes = [Cesium.CameraEventType.LEFT_DRAG]
      map.scene.screenSpaceCameraController.rotateEventTypes = [Cesium.CameraEventType.RIGHT_DRAG]
      //像素比
      map.viewer.resolutionScale = window.devicePixelRatio
      // 获取WebGL上下文
      var gl = map.viewer.scene.context._gl;
      var maxSamples = gl.getParameter(gl.MAX_SAMPLES);
      //限制视角范围
      var cameraHistory = new mars3d.thing.CameraHistory({
        limit: {
          position: Cesium.Cartesian3.fromDegrees(104.386, 31.105, 50),
          radius: 200000.0,
          debugExtent: false,
        },
        maxCacheCount: 9999
      })
      map.addThing(cameraHistory)
      
      //取消右键context
      defaultContextmenuItems = this.defaultContextmenuItems = map.getDefaultContextMenu()
      map.unbindContextMenu()
      //定义2个图层
      baseLayer = new mars3d.layer.GraphicLayer() //放基本的
      mainLayer = new mars3d.layer.GraphicLayer() //放各类图形
      drawDebugLayer = this.drawDebugLayer = new mars3d.layer.GraphicLayer({ allowDrillPick: true })

      map.addLayer(baseLayer)
      map.addLayer(mainLayer)
      map.addLayer(drawDebugLayer)

      //创建地图
      this.createMaps()

      //创建组
      this.createGroups()

      //效果集合
      this.createEffect()

      //创建各类要素
      this.initSomeEntitys()


    },

    //创建地图
    createMaps() {
      var MapboxLayerDark = new mars3d.layer.MapboxLayer({
        id: 'MapboxLayerDark',
        show: true,
        name: 'MapboxLayerDark',
        url: `https://api.mapbox.com/styles/v1/`,
        username: "liukaiyuan1102",
        styleId: "cm1so06lz00kr01r74rilg5yk",
        accessToken: "pk.eyJ1IjoibGl1a2FpeXVhbjExMDIiLCJhIjoiY2xreHR3bXBrMWRpOTNybXl2MTBkcWhuaiJ9.MtWuDuCVnzgETbXO0-fq3Q",
        scaleFactor: true,
        brightness: 1.3,
      })
      map.addLayer(MapboxLayerDark)

      var MapboxLayerLight = new mars3d.layer.MapboxLayer({
        id: 'MapboxLayerLight',
        show: false,
        name: 'MapboxLayerLight',
        url: `https://api.mapbox.com/styles/v1/`,
        username: "liukaiyuan1102",
        styleId: "cm1lhyjcc073101pqfieq73o7",
        accessToken: "pk.eyJ1IjoibGl1a2FpeXVhbjExMDIiLCJhIjoiY2xreHR3bXBrMWRpOTNybXl2MTBkcWhuaiJ9.MtWuDuCVnzgETbXO0-fq3Q",
        scaleFactor: true,
        brightness: 1,
      })
      map.addLayer(MapboxLayerLight)

    },
    //切换地图
    switchBaseMap() {
      var MapboxLayerDark = map.getLayer("MapboxLayerDark")
      var MapboxLayerLight = map.getLayer("MapboxLayerLight")
      var deyang_city1 = map.getLayer("deyang_city1", "id") //市区白模
      if (MapboxLayerDark.show == true) {
        //亮
        MapboxLayerDark.show = false
        MapboxLayerLight.show = true
        deyang_city1.customShader.uniforms.u_colorBottom.value = Cesium.Color.fromCssColorString('#171d36')
        deyang_city1.customShader.uniforms.u_colorTop.value = Cesium.Color.fromCssColorString('#7083bd')
        deyang_city1.customShader.uniforms.u_bottomToplerp.value = 100
        deyang_city1.customShader.uniforms.u_baseHeight.value = 400
        deyang_city1.customShader.uniforms.u_heightRange.value = 20
        deyang_city1.customShader.uniforms.u_glowRange.value = 500
      } else {
        //暗
        MapboxLayerDark.show = true
        MapboxLayerLight.show = false
        deyang_city1.customShader.uniforms.u_colorBottom.value = Cesium.Color.fromCssColorString(this.u_colorBottom)
        deyang_city1.customShader.uniforms.u_colorTop.value = Cesium.Color.fromCssColorString(this.u_colorTop)
        deyang_city1.customShader.uniforms.u_bottomToplerp.value = this.u_bottomToplerp
        deyang_city1.customShader.uniforms.u_baseHeight.value = this.u_baseHeight
        deyang_city1.customShader.uniforms.u_heightRange.value = this.u_heightRange
        deyang_city1.customShader.uniforms.u_glowRange.value = this.u_glowRange
      }
    },

    //显隐管道
    showOrHidePipeline() {
      this.isShowPipeline = !this.isShowPipeline;
      var MapboxLayerDark = map.getLayer("MapboxLayerDark") //暗色地图
      var MapboxLayerLight = map.getLayer("MapboxLayerLight") //亮色地图
      var deyang_city1 = map.getLayer("deyang_city1") //市区白模

      if (this.isShowPipeline == true) {
        MapboxLayerDark.brightness = 0.85
        MapboxLayerLight.brightness = 0.9
        deyang_city1.opacity = 0.4
        // terrainPlanClip.enabled = true
        //POI-监控
        groups['视频POI'].forEach((item) => {
          item.show = true
        })
        groups['泵站POI'].forEach((item) => {
          item.show = true
        })
        //其他
        groups["雨水管网模型"].forEach((item) => {
          item.show = true
        })
        groups['横向文本'].forEach((item) => {
          item.show = true
        })
        // groups['竖向文本'].forEach((item) => {
        //   item.show = true
        // })
        groups['WarningPOI'].forEach((item) => {
          item.show = true
        })
        groups['路网'].forEach((item) => {
          item.opacity = 0.3
        })
      }
      else {
        MapboxLayerDark.brightness = 1.3
        MapboxLayerLight.brightness = 1
        deyang_city1.opacity = 1
        // terrainPlanClip.enabled = false
        //POI-监控
        groups['视频POI'].forEach((item) => {
          item.show = false
        })
        groups['泵站POI'].forEach((item) => {
          item.show = false
        })
        //其他
        groups["雨水管网模型"].forEach((item) => {
          item.show = false
        })
        groups['横向文本'].forEach((item) => {
          item.show = false
        })
        // groups['竖向文本'].forEach((item) => {
        //   item.show = false
        // })
        groups['WarningPOI'].forEach((item) => {
          item.show = false
        })
        groups['路网'].forEach((item) => {
          item.opacity = 1
        })
      }
    },

    //各类组
    createGroups() {
      //POI
      groups["泵站POI"] = []
      groups["视频POI"] = []
      groups["在线雨量监测POI"] = []
      groups["智能井盖POI"] = []
      groups["渠道雷达POI"] = []
      groups["渠道溶解氧POI"] = []
      groups["渠道透明度POI"] = []
      groups["渠道氨氮POI"] = []
      groups["渠道氧化还原POI"] = []
      groups["雨水管网液位POI"] = []
      groups["污水管网流量POI"] = []
      groups["污水管网液位POI"] = []
      groups["内涝点POI"] = []
      //报警POI组
      groups['WarningPOI'] = []
      //模型及其他
      groups["雨水管网模型"] = []
      groups["污水管网模型"] = []
      groups['横向文本'] = []
      groups['竖向文本'] = []
      groups["河流"] = []
      groups['水路'] = []
      groups["路网"] = []
      groups['边界'] = []

    },

    //创建各类要素--demo------------------------
    async initSomeEntitys() {
      //创建倾斜摄影
      this.initPhotography()

      //创建路网、边界
      var [lineroute, linewall] = this.createRoutes()
      map.addLayer(lineroute);
      map.addLayer(linewall);
      groups['路网'].push(lineroute);
      groups['边界'].push(linewall);

      //烟花
      this.createFirework()

      //创建官网挖地效果
      // this.createTerrainPlanClip('json/dy_terrainclip.json')

      //创建树
      // this.createTrees()

      //创建雨水管网模型
      var pipelineLayer = this.createPipelineLayer();
      map.addLayer(pipelineLayer);
      groups["雨水管网模型"].push(pipelineLayer)

      //创建视频POI
      var cameraPOI = this.poiCreateHls({
        id: 23124,
        title: '广电门口',
        hlsUrl: 'https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8',
        lng: 104.385034,
        lat: 31.102377,
        alt: 460.6,
      });
      mainLayer.addGraphic(cameraPOI);
      groups['视频POI'].push(cameraPOI);

      //创建POI
      var poi = this.poiCreate('泵站POI', { lng: 104.403040, lat: 31.09612, alt: 435, id: 123 });
      mainLayer.addGraphic(poi);
      groups['泵站POI'].push(poi);
      //创建告警
      var warnpoi = this.createWarningCircle({ lng: 104.403040, lat: 31.09612, alt: 435, id: 123, clampToGround: true, radius: 150 })
      mainLayer.addGraphic(warnpoi);
      groups['WarningPOI'].push(warnpoi);

      //创建 竖向文本
      const lineTipsTexts = [
        { lng: 104.332092475273, lat: 31.096527128985, alt: 446, text: '天元污水厂', show: true },
        { lng: 104.396095470405, lat: 31.075042744910, alt: 435, text: '柳沙堰污水厂', show: true },
        { lng: 104.414205669747, lat: 31.031873410829, alt: 427, text: '绵远河污水厂', show: true },
        { lng: 104.362853218209, lat: 31.054543781240, alt: 434, text: '石亭江污水厂', show: true },
      ];
      lineTipsTexts.forEach(item => {
        var upText = this.createUpText(item);
        groups['竖向文本'].push(upText);
        mainLayer.addGraphic(upText)
      });

      //创建指示线文本
      var lineTipText = this.createlineTipText({
        name: '五洲广场全景', lng: 104.388, lat: 31.10385, clampToGround: true, alt: 650, attr: { url: "https://www.720yun.com/t/73vk6hr7p8y?scene_id=108080297" }
      })
      mainLayer.addGraphic(lineTipText);
      groups['横向文本'].push(lineTipText);
      //绑定Popup打开全景图
      lineTipText.bindPopup((event) => {
        const attr = event.graphic.attr || {};
        if (!attr) return;
        return `<iframe style="margin-top: 14px;pointer-events: all; width: 600px; height: 300px; border: none; "src="${attr.url}"></iframe> `
      })



      //创建河流1
      var waterLight1 = await this.createOneRiver("河流1", 'json/dy_water1.json')
      mainLayer.addGraphic(waterLight1);
      groups['河流'].push(waterLight1);
      //创建河流2
      var waterLight2 = await this.createOneRiver("河流2", 'json/dy_water2.json')
      mainLayer.addGraphic(waterLight2);
      groups['河流'].push(waterLight2);
    },

    //倾斜摄影
    initPhotography() {
      var CustomShader = (MC = "z") => {
        return new Cesium.CustomShader({
          uniforms: {
            u_envTexture: {
              value: new Cesium.TextureUniform({
                url: require("../assets/textures/buildings-kj.jpg")
              }),
              type: Cesium.UniformType.SAMPLER_2D
            },
            u_lightPosition: {
              type: Cesium.UniformType.VEC3,
              value: Cesium.Cartesian3.fromDegrees(104.05, 31.05, 400)
            },
            u_lightColor: {
              type: Cesium.UniformType.VEC3,
              value: Cesium.Color.fromCssColorString("#f00")
            },
            u_lightRadius: {
              type: Cesium.UniformType.FLOAT,
              value: 200
            },

            u_colorBottom: {
              type: Cesium.UniformType.VEC3,
              value: Cesium.Color.fromCssColorString(this.u_colorBottom)
            },
            u_colorTop: {
              type: Cesium.UniformType.VEC3,
              value: Cesium.Color.fromCssColorString(this.u_colorTop)
            },
            u_bottomToplerp: {
              type: Cesium.UniformType.FLOAT,
              value: this.u_bottomToplerp
            },
            //底部基准高度
            u_baseHeight: {
              type: Cesium.UniformType.FLOAT,
              value: this.u_baseHeight
            },
            //建筑高除的分子
            u_heightRange: {
              type: Cesium.UniformType.FLOAT,
              value: this.u_heightRange
            },
            //光环范围
            u_glowRange: {
              type: Cesium.UniformType.FLOAT,
              value: this.u_glowRange
            },

          },
          mode: Cesium.CustomShaderMode.REPLACE_MATERIAL,
          lightingModel: Cesium.LightingModel.UNLIT,
          fragmentShaderText: `
            #define sat( a ) clamp( a, 0.0, 1.0 )
            float getDistanceDecay( float lightDistance, float distance, float decay) {
              if ( distance > 0.0 && decay > 0.0 ) {
                  return pow( sat( - lightDistance / distance + 1.0 ), decay );
              }
              return 1.0;
            }
            vec3 addPointLight(vec3 lightPosition, vec3 lightColor, vec3 positionWC , vec3 normal){
              float distance = u_lightRadius;
              float decay = 2.0;
              float lightDistance = length( lightPosition - positionWC );
              lightColor *= getDistanceDecay( lightDistance, distance, decay );
              return lightColor;
            }
            void fragmentMain(FragmentInput fsInput,inout czm_modelMaterial material) {
              vec3 positionMC = fsInput.attributes.positionMC;
              vec3 positionEC = fsInput.attributes.positionEC;
              vec3 normalEC = fsInput.attributes.normalEC;
              vec3 posToCamera = normalize(-positionEC);
              vec2 uv = fsInput.attributes.texCoord_0;
              float diffuseCoefficient = max(0.0, dot(normalEC, vec3(0.1)) * 1.0);
              vec4 glColor2 = vec4(0.);
              {
                vec3 coord = normalize(vec3(czm_inverseViewRotation * reflect(posToCamera, normalEC)));
                vec4 darkRefColor = texture(u_envTexture, vec2(coord.x, (coord.z - coord.y) / 2.0));
                //渐变颜色+背景图
                glColor2.rgb = mix(
                  mix(u_colorBottom, u_colorTop, clamp(positionMC.${MC} / u_bottomToplerp, 0.0, 1.0)), 
                  darkRefColor.rgb, 
                  0.1
                );
                //点乘阴影
                glColor2.rgb *= min(diffuseCoefficient + 0.1, 1.0);

                //高亮
                glColor2.rgb += addPointLight(
                  u_lightPosition ,
                  u_lightColor,
                  (czm_model * vec4(positionMC, 1.0)).xyz ,
                  normalEC
                );

                float czm_height = positionMC.${MC} - u_baseHeight;
                float czm_a11 = fract(czm_frameNumber / 120.0) * 3.14159265 * 2.0;
                float czm_a12 = czm_height / u_heightRange + sin(czm_a11) * 0.1;
                float times = czm_frameNumber / 60.0;
                glColor2.rgb *= vec3(czm_a12);// 渐变
                float time = fract(czm_frameNumber / 180.0);
                //光圈速度
                time = abs(time - 0.5) * 3.0;
                float czm_h = clamp(czm_height / u_glowRange, 0.0, 1.0);
                //光圈宽度
                float diff_yz = 0.001;
                float czm_diff = step(diff_yz, abs(czm_h - time));
                //光圈颜色
                vec3 diff_color = vec3(.2,.2,.6);
                glColor2.rgb += diff_color * (1.0 - czm_diff);
                glColor2.a = 1.0;
              }
              material.diffuse = glColor2.rgb;
              material.alpha = glColor2.a;
          }`

        })
      }

      //城市白模
      let deyang_city1 = new mars3d.layer.TilesetLayer({
        id: 'deyang_city1',
        name: 'deyang_city1',
        zIndex: 20,
        // url: window.basePathUrl + '_3dtile/deyang/city/tileset.json',
        url: window._3dtileBaseUrl + '/model/TXuc47De/tileset.json',
        maximumScreenSpaceError: 1,
        position: {
          lng: 104.3875,
          lat: 31.104,
          alt: -72
        },
        popup: '',
        backFaceCulling: true,
        clip: {
          precise: false,
          enabled: true
        },
        customShader: CustomShader()
      })
      map.addLayer(deyang_city1)

      // map.on("click", function (e) {
      //   deyang_city1.customShader.uniforms.u_lightPosition.value = e.cartesian
      // })

      /*
        var threeLayer = new ThreeLayer()
        map.addLayer(threeLayer)
        const holographicMaterial = new HolographicMaterial();
        const ogc3DTile = new OGC3DTile({
          url: window._3dtileBaseUrl + '/model/TXuc47De/tileset.json',
          renderer: threeLayer.renderer,
        });
        ogc3DTile.material = holographicMaterial
        threeLayer.scene.add(ogc3DTile)
        threeLayer.ogc3DTiles.push(ogc3DTile)
      */


      /*
      let deyang_city2 = new mars3d.layer.TilesetLayer({
        id: 'deyang_city2',
        name: 'deyang_city2',
        zIndex: 20,
        url: window._3dtileBaseUrl + '/model/yDvvdlRU/tileset.json',
        maximumScreenSpaceError: 1,
        cacheBytes: 1073741824 * 1,//额定显存
        maximumCacheOverflowBytes: 2147483648 * 1,//最大显存
        position: {
          // lng: 104.393747,
          // lat: 31.1074,
          alt: 446
        },
        popup: '',
        backFaceCulling: true,
        clip: {
          precise: false,
          enabled: true
        },
        customShader: CustomShader2(),
      })
      map.addLayer(deyang_city2)
      */

    },

    //效果
    createEffect() {
      const OfflineCache = CesiumNetworkPlug.OfflineCacheController
      OfflineCache.ruleList.add("https://api.mapbox.com/")
      OfflineCache.ruleList.add("http://data.mars3d.cn/")


      // 修改天空盒
      map.scene.skyBoxNearDistance = 1.0;
      map.scene.skyBox = new Cesium.SkyBox({
        sources: {
          negativeX: require('../assets/textures/skybox/tycho2t3_80_mx.jpg'),
          negativeY: require('../assets/textures/skybox/tycho2t3_80_my.jpg'),
          negativeZ: require('../assets/textures/skybox/tycho2t3_80_mz.jpg'),
          positiveX: require('../assets/textures/skybox/tycho2t3_80_px.jpg'),
          positiveY: require('../assets/textures/skybox/tycho2t3_80_py.jpg'),
          positiveZ: require('../assets/textures/skybox/tycho2t3_80_pz.jpg'),
        }
      })

      //阴影
      map.viewer.shadows = false
      map.viewer.shadowMap.size = 2048
      map.viewer.shadowMap.softShadows = false
      map.viewer.shadowMap.maximumDistance = 4000
      //雾
      map.scene.fog.density = 0
      map.scene.fog.minimumBrightness = 0.5
      //大气
      map.scene.globe.atmosphereLightIntensity = 30
      map.scene.globe.atmosphereBrightnessShift = -0.01
      //AO
      map.scene.postProcessStages.ambientOcclusion.enabled = false
      map.scene.postProcessStages.ambientOcclusion.uniforms.intensity = 2
      map.scene.postProcessStages.ambientOcclusion.uniforms.bias = 0.12
      map.scene.postProcessStages.ambientOcclusion.uniforms.lengthCap = 0.5
      map.scene.postProcessStages.ambientOcclusion.uniforms.stepSize = 2
      map.scene.postProcessStages.ambientOcclusion.uniforms.blurStepSize = 1.5
      //HDR
      map.scene.highDynamicRange = false
      //泛光效果
      const bloomEffect = new mars3d.effect.BloomEffect()
      bloomEffect.brightness = 2
      bloomEffect.enabled = false
      map.addEffect(bloomEffect)
      //边缘光
      // outlineEffect = new mars3d.effect.OutlineEffect({
      //   enabled: true,
      //   color: "#FFFF00",
      //   colorHidden: "#FFFF00",
      //   width: 2,
      //   eventType: false,
      //   showPlane: true,
      //   planeAngle: 3,
      //   glow: false,
      // })
      // map.addEffect(outlineEffect)

      //颜色校正
      var ColorCorrectionEffect = new mars3d.effect.ColorCorrectionEffect({
        enabled: true,
        contrast: 1, //1.0,
        hue: 0, //0.0,
        brightness: 1,
        saturation: 1
      })
      map.addEffect(ColorCorrectionEffect)

      //地下模式
      // underground = new mars3d.thing.Underground({alpha:1,enabled:true})
      // map.addThing(underground)

    },

    //创建指示线文本
    createlineTipText({ id = '', lng = '', lat = '', alt = '', name = '', clampToGround = false, attr = {} }) {
      var lineTipText = new mars3d.graphic.DivGraphic({
        id: id || name,
        show: false,
        name: name,
        position: [lng, lat, alt],
        style: {
          html: `<div class="marsBlackPanel">
                  <div class="marsBlackPanel-text" style="pointer-events: all;">${name}</div>
              </div>`,
          horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
          verticalOrigin: Cesium.VerticalOrigin.CENTER,
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 400000),
          clampToGround: clampToGround,
          highlight: {
            // type: mars3d.EventType.click,
            className: 'marsBlackPanel-highlight'
          }
        },
        attr: attr
      })
      lineTipText.on(mars3d.EventType.click, (e) => {
        // var text = e.target.container.querySelector(".marsBlackPanel-text").innerHTML;
        var toCartesian3 = Cesium.Cartesian3.fromDegrees(lng, lat, alt * 1 + 200);
        map.cancelFlyTo().flyToPositions([toCartesian3], {
          duration: 1,
          radius: 500, //距离
          // heading: Math.random() * 360,
          pitch: -70,
          roll: 0,
          complete: () => { }
        })
      })
      return lineTipText;
    },

    //创建竖向文本
    createUpText({ text = '', show = false, id = '', lng = '', lat = '', alt = '', clampToGround = false, attr = {}, }) {
      const graphic = new mars3d.graphic.DivUpLabel({
        id: id || text,
        show: show,
        position: new mars3d.LngLatPoint(lng, lat, alt),
        style: {
          text: text,
          color: "#fff",
          font_size: 9,
          font_family: "微软雅黑",
          lineHeight: 16, //底部线高度
          circleSize: 0,
          clampToGround: clampToGround,
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1000000)
        },
        attr: attr,
      })
      return graphic;
    },

    //创建路网、边界线、边界墙
    createRoutes() {
      const lineroute = new mars3d.layer.GeoJsonLayer({
        name: "市区道路",
        url: basePathUrl + 'json/route_small.geojson',
        opacity: 1,
        toPrimitive: true,
        // crs: "EPSG:3857",
        // chinaCRS: mars3d.ChinaCRS.WGS84,
        symbol: {
          styleOptions: {
            width: 1.7,
            clampToGround: true,
            materialType: mars3d.MaterialType.ODLine,
            materialOptions: {
              bgColor: new Cesium.Color(80 / 255, 128 / 255, 222 / 255, 0.35),
              color: new Cesium.Color(Math.random() * 0.5 + 0.5, Math.random() * 0.8 + 0.2, 0.0, 0.7),
              speed: 2,
              startTime: Math.random(),
              bidirectional: 0,
            }
          }
        },
        popup: "",
        show: true,
      })
      const linewall = new mars3d.layer.GeoJsonLayer({
        name: "德阳边界线",
        url: basePathUrl + 'json/deyang_bounds.json',
        symbol: {
          type: "polyline",
          styleOptions: {
            color: "rgba(255,255,255,0.3)",
            width: 1.5,
            clampToGround: true,
            label: {
              text: "{name}",
              position: "center",
              font_size: 18,
              color: "#f9f9f9",
              font_family: "微软雅黑",
              outline: true,
              outlineColor: "#000",
              outlineWidth: 3,
              scaleByDistance: true,
              scaleByDistance_far: 20000000,
              scaleByDistance_farValue: 0.1,
              scaleByDistance_near: 1000,
              scaleByDistance_nearValue: 1
            }
          },
        },
      })
      return [lineroute, linewall]
    },
    //创建一条湖泊 
    createOneRiver(name, json) {
      return new Promise((r, j) => {
        mars3d.Util.fetchJson({ url: basePathUrl + json }).then((data) => {
          // const dynamicRiver = new mars3d.graphic.ReflectionWater({
          //   show: true,
          //   name: name + '-1',
          //   positions: data.map(item => {
          //     return [item._lng, item._lat, item._alt]
          //   }),
          //   style: {
          //     normalMap: require('../assets/textures/waterNormals.jpg'),
          //     ripple: 1000, //波纹大小（数值越大，波纹越密集）
          //     distortion: 20, //倒影扭曲
          //     reflectivity: 0.6,
          //     specularIntensity: 0.2,
          //     color: "#1663e0",
          //     farColor: "#1663e0",
          //     farDistance: 1000000,
          //     animationSpeed: 2,
          //     clampToGround: true,
          //   }
          // })
          const waterLight = new mars3d.graphic.PolygonPrimitive({
            show: true,
            name: name,
            positions: data.map(item => {
              return [item._lng, item._lat, item._alt]
            }),
            style: {
              materialType: mars3d.MaterialType.WaterLight,
              materialOptions: {
                specularMap: require('../assets/textures/poly-stone.jpg'),
                normalMap: require('../assets/textures/waterNormals.jpg'),
                alpha: 0.4
              },
              clampToGround: true,
            },
          })
          r(waterLight);
        })
      })
    },
    //创建全市湖泊 
    createCityFullRiver() {
      const createR = ()=>{
        mars3d.Util.fetchJson({ url: basePathUrl + 'json/dy_full_river.geojson' }).then((data) => {
          data.forEach(item => {
            const river = new mars3d.graphic.PolygonPrimitive({
              show: true,
              name: "河流",
              positions: item.geometry.coordinates[0][0].map(v => [v[0], v[1], 0]),
              style: {
                materialType: mars3d.MaterialType.WaterLight,
                materialOptions: {
                  specularMap: require('../assets/textures/poly-stone.jpg'),
                  normalMap: require('../assets/textures/waterNormals.jpg'),
                  alpha: 0.5
                },
                clampToGround: true,
              },
            })
            groups['河流'].push(river);
          })
          map.cancelFlyTo().flyToPositions([Cesium.Cartesian3.fromDegrees(104.4, 31.1, 600)], {
            duration: 1,
            radius: 50000,
            heading: 20,
            pitch: -50,
            roll: 0,
            complete: () => {
              mainLayer.addGraphic([...groups['河流']]);
            }
          })
        })
      }
      if(groups['河流'].length == 2){
        groups['河流'].forEach(g => {
          mainLayer.removeGraphic(g)
        })
        groups['河流'] = []
        createR();
      }else if(groups['河流'].length == 0){
        createR();
      }else{
        groups['河流'].forEach(g => {
          mainLayer.removeGraphic(g)
        })
        groups['河流'] = []
      }
    },
    //创建全市水路 
    createWaterRoute() {
      if(groups['水路'].length != 0){
        groups['水路'].forEach(g => {
          mainLayer.removeGraphic(g)
        })
        groups['水路'] = []
      }else{
        mars3d.Util.fetchJson({ url: basePathUrl + 'json/dy_full_waterroute.geojson' }).then((data) => {
          data.forEach(item => {
            var cc = item.geometry.coordinates[0];
            const river = new mars3d.graphic.PolylinePrimitive({
              show: true,
              name: "水路",
              positions: cc.map(v => [v[0], v[1], 0]),
              style: {
                width: 4,
                materialType: mars3d.MaterialType.LineFlow,
                materialOptions: {
                  image: require('../assets/textures/arrow-h.png'),
                  axisY: false,
                  repeat: new Cesium.Cartesian2(20.0 + cc.length, 1.0),
                  color: "#bdec13",
                  opacity: 0.4,
                  speed: 20
                },
                clampToGround: true,
              },
            })
            groups['水路'].push(river);
          })
          map.cancelFlyTo().flyToPositions([Cesium.Cartesian3.fromDegrees(104.4, 31.1, 600)], {
            duration: 1,
            radius: 50000,
            heading: 20,
            pitch: -50,
            roll: 0,
            complete: () => {
              mainLayer.addGraphic([...groups['水路']]);
            }
          })
        })
      }
    },

    //创建挖地 
    createTerrainPlanClip(json) {
      if (!terrainPlanClip) {
        terrainPlanClip = new mars3d.thing.TerrainClip({
          enabled: false,
          diffHeight: 30,
          exact: true,
          image: require('../assets/textures/poly-soil.jpg'),
          imageBottom: require('../assets/textures/poly-soil.jpg'),
          splitNum: 50 // 井边界插值数
        })
        map.addThing(terrainPlanClip)
      }
      return new Promise((r, j) => {
        mars3d.Util.fetchJson({ url: basePathUrl + json }).then((data) => {
          // console.log(data)
          terrainPlanClip.addArea(data.map(ii => {
            return [ii._lng, ii._lat, ii._alt]
          }))
          r(terrainPlanClip);
        })
      })
    },

    //创建烟花
    createFirework() {
      Cesium.Math.setRandomNumberSeed(315);
      const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
        Cesium.Cartesian3.fromDegrees(104.3879, 31.1038, 510)
      );
      const emitterInitialLocation = new Cesium.Cartesian3(0.0, 100.0, 200.0);

      let particleCanvas;

      function getImage() {
        if (!Cesium.defined(particleCanvas)) {
          particleCanvas = document.createElement("canvas");
          particleCanvas.width = 20;
          particleCanvas.height = 20;
          const context2D = particleCanvas.getContext("2d");
          context2D.beginPath();
          context2D.arc(6, 6, 6, 0, Cesium.Math.TWO_PI, true);
          context2D.closePath();
          context2D.fillStyle = "rgb(255, 255, 255)";
          context2D.fill();
        }
        return particleCanvas;
      }

      const minimumExplosionSize = 50.0;
      const maximumExplosionSize = 500.0;
      const burstSize = 100.0;
      const lifetime = 20.0;
      const numberOfFireworks = 2.0;

      const emitterModelMatrixScratch = new Cesium.Matrix4();

      function createFirework(offset, color, bursts) {
        const position = Cesium.Cartesian3.add(
          emitterInitialLocation,
          offset,
          new Cesium.Cartesian3()
        );
        const emitterModelMatrix = Cesium.Matrix4.fromTranslation(
          position,
          emitterModelMatrixScratch
        );
        const particleToWorld = Cesium.Matrix4.multiply(
          modelMatrix,
          emitterModelMatrix,
          new Cesium.Matrix4()
        );
        const worldToParticle = Cesium.Matrix4.inverseTransformation(
          particleToWorld,
          particleToWorld
        );

        const size = Cesium.Math.randomBetween(
          minimumExplosionSize,
          maximumExplosionSize
        );
        const particlePositionScratch = new Cesium.Cartesian3();
        const force = function (particle) {
          const position = Cesium.Matrix4.multiplyByPoint(
            worldToParticle,
            particle.position,
            particlePositionScratch
          );
          if (Cesium.Cartesian3.magnitudeSquared(position) >= size * size) {
            Cesium.Cartesian3.clone(
              Cesium.Cartesian3.ZERO,
              particle.velocity
            );
          }
        };

        const normalSize =
          (size - minimumExplosionSize) /
          (maximumExplosionSize - minimumExplosionSize);
        const minLife = 0.3;
        const maxLife = 1.0;
        const life = normalSize * (maxLife - minLife) + minLife;
        const imageSize = Math.random() * 1.5 + 3;
        map.viewer.scene.primitives.add(
          new Cesium.ParticleSystem({
            image: getImage(),
            startColor: color,
            endColor: color.withAlpha(0.1),
            particleLife: life,
            minimumParticleLife: Math.max(life - 0.5, 0.3),
            maximumParticleLife: life + 0.5,
            speed: 100.0,
            imageSize: new Cesium.Cartesian2(imageSize, imageSize),
            emissionRate: 3,
            emitter: new Cesium.SphereEmitter(0.5),
            bursts: bursts,
            lifetime: lifetime,
            updateCallback: force,
            modelMatrix: modelMatrix,
            emitterModelMatrix: emitterModelMatrix,
          })
        );
      }

      const xMin = -100.0;
      const xMax = 100.0;
      const yMin = -80.0;
      const yMax = 100.0;
      const zMin = -50.0;
      const zMax = 50.0;

      const colorOptions = [
        {
          red: 0.95,
          green: 0.55,
          blue: 0.1,
          alpha: 0.8,
        },
        {
          red: 0.1,
          green: 0.95,
          blue: 0.94,
          alpha: 0.8,
        },
      ];

      for (let i = 0; i < numberOfFireworks; ++i) {
        const x = Cesium.Math.randomBetween(xMin, xMax);
        const y = Cesium.Math.randomBetween(yMin, yMax);
        const z = Cesium.Math.randomBetween(zMin, zMax);
        const offset = new Cesium.Cartesian3(x, y, z);
        const color = Cesium.Color.fromRandom(
          colorOptions[i % colorOptions.length]
        );

        const bursts = [];
        for (let j = 0; j < 3; ++j) {
          bursts.push(
            new Cesium.ParticleBurst({
              time: Cesium.Math.nextRandomNumber() * lifetime,
              minimum: burstSize,
              maximum: burstSize,
            })
          );
        }

        createFirework(offset, color, bursts);
      }
    },

    //创建云
    createClouds() {
      function randomPoint() {
        const jd = getRandomNumberInRange(104.1 * 1000, 104.6 * 1000) / 1000
        const wd = getRandomNumberInRange(30.8 * 1000, 31.5 * 1000) / 1000
        const height = getRandomNumberInRange(2200, 3300)
        return new mars3d.LngLatPoint(jd, wd, height)
      }
      function getRandomNumberInRange(minValue, maxValue) {
        return minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue)
      }
      for (let j = 0; j < 10; ++j) {
        const position = randomPoint()
        const scaleX = getRandomNumberInRange(10000, 20000)
        const scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0)
        const depth = getRandomNumberInRange(300, 500)
        const aspectRatio = getRandomNumberInRange(1.5, 2.1)
        const cloudHeight = getRandomNumberInRange(5, 20)

        const graphic = new mars3d.graphic.CloudPrimitive({
          position,
          style: {
            scale: new Cesium.Cartesian2(scaleX, scaleY),
            maximumSize: new Cesium.Cartesian3(aspectRatio * cloudHeight, cloudHeight, depth),
            slice: getRandomNumberInRange(0.2, 0.6),
            brightness: getRandomNumberInRange(0.4, 0.8),
          }
        })
        effectLayer.addGraphic(graphic)
      }

    },

    //创建树-----------------------------------
    createTrees() {
      mars3d.Util.fetchJson({ url: basePathUrl + 'json/tree1.json' }).then((data) => {
        for (var i = 0; i < data.length; i++) {
          const treeModel = new mars3d.graphic.ModelPrimitive({
            name: "tree",
            position: [
              data[i][0],
              data[i][1],
              data[i][2],
            ],
            style: {
              scaleX: 3,
              scaleZ: Math.random() * 1.5 + 2,
              scaleY: 3,
              heading: Math.random() * 360,
              // pitch: 0,
              // roll: 0,
              minimumPixelSize: 0,
              url: basePathUrl + 'models/tree_1.glb',
            },
          })
          effectLayer.addGraphic(treeModel)
        }
      })
    },

    //创建监控视频----------
    poiCreateHls(params) {
      const graphicImg = new mars3d.graphic.DivGraphic({
        id: params.id,
        name: `poi_camera_${params.id}_${params.title}`,
        show: false,
        position: [params.lng, params.lat, params.alt],
        style: {
          html: ` <div class="mars3d-camera-content">
                      <img class="mars3d-camera-img" style="pointer-events: all;" src="${require('../assets/textures/camera.png')}" >
                    </div>
                    <div class="mars3d-camera-line" style="pointer-events: none;height: 24px;border-left-color:#fff;"></div>
                    <div class="mars3d-camera-point" style="pointer-events: none;display:none;"></div>
                  `,
          offsetX: -0,
          // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 100000)
        },
        popup: `<div id="dplayer" style="width:300px;height:180px;"></div>`,
        popupOptions: {
          offsetX: 14,
          offsetY: -106,
          template: `<div class="marsBlueGradientPnl" style="padding-top: 22px;pointer-events: all;">
                        <div style="position:absolute;left:8px;top:2px;color:#fff;font-size:12px;z-index:9999">${params.title}</div>
                        <div class="marsBlackPanel-text">{content}</div>
                        <span class="closeButton mars3d-popup-close-button">X</span>
                      </div>`,
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM
        }
      })
      graphicImg.on(mars3d.EventType.mouseOver, (event) => {
        graphicImg.openSmallTooltip(event.windowPosition, `${params.title}`)
      })
      graphicImg.on(mars3d.EventType.mouseOut, (event) => {
        graphicImg.closeSmallTooltip()
      })
      graphicImg.on(mars3d.EventType.popupOpen, function (event) {
        //前往目标点
        var toCartesian3 = Cesium.Cartesian3.fromDegrees(params.lng, params.lat, params.alt * 1 + 200);
        map.cancelFlyTo().flyToPositions([toCartesian3], {
          duration: 1,
          radius: 500,
          // heading: Math.random() * 360,
          pitch: -70,
          roll: 0,
          complete: () => { }
        })
        //请求其他获取数据----------------------------------------
        setTimeout(() => {
          const dp = new DPlayer({
            container: event.container.querySelector('#dplayer'),
            video: {
              url: params.hlsUrl,
              type: 'customHls',
              customType: {
                customHls: function (video, player) {
                  const hls = new Hls()
                  hls.loadSource(video.src)
                  hls.attachMedia(video)
                }
              }
            }
          })
          dp.play()
        }, 1000)
      })

      return graphicImg;
    },

    //创建管道-------------------------
    createPipelineLayer() {
      const tiles3dLayer2 = new mars3d.layer.TilesetLayer({
        show: false,
        name: "雨水管网模型",
        url: "//data.mars3d.cn/3dtiles/max-piping/tileset.json",
        position: { lng: 104.4023, lat: 31.0973, alt: 400 },
        // rotation: { z: 0 },
        maximumScreenSpaceError: 2,
        highlight: {
          enabled: false,
        },
        attr: { remark: "" },
      })

      return tiles3dLayer2;
    },

    //创建POI--------
    poiCreate(type, detail = {}) {
      var poiIcon = {
        "泵站POI": require("../assets/textures/marker.png"),

      };
      const graphic = new mars3d.graphic.BillboardEntity({
        id: detail.id,
        name: `poi_${type}_${detail.id}`,
        show: false,
        position: new mars3d.LngLatPoint(detail.lng, detail.lat, detail.alt),
        style: {
          image: poiIcon[type],
          visibleDepth: false, //是否被遮挡
          width: 36,
          height: 36,
          opacity: 1,
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        },
        allowDrillPick: false, //是否允许鼠标穿透拾取
        attr: { remark: "" },
        popup: `<div style="width:300px;height:180px;color:#fff;position:relative;">
                  <div class="xyzz">酸度：432</div>


                  <div class="loading" style="display:none;position:absolute;left:0;top:0;width:100%;height:100%;color:#eee;display:flex;align-items:center;justify-content:center;background: #000;">加载中...</div>
                </div>`,
        popupOptions: {
          offsetX: 0,
          offsetY: -44,
          template: `<div class="marsBlueGradientPnl" style="padding-top: 22px;pointer-events: none;position: relative;top: -0px">
                        <div style="position:absolute;left:8px;top:2px;color:#fff;font-size:12px;z-index:9999">一号监测点</div>
                        <div class="marsBlackPanel-text" style="pointer-events: all;">{content}</div>
                        <div class="mars3d-camera-line" style="pointer-events: none;height: 24px;border-left-color:#fff;    box-shadow: 0 0 9px #fff;"></div>
                        <div class="mars3d-camera-point" style="pointer-events: none;display:none;"></div>
                        <span class="closeButton mars3d-popup-close-button" style="pointer-events: all;">X</span>
                      </div>`,
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM
        }
      });
      graphic.on(mars3d.EventType.mouseOver, (event) => {
        graphic.openSmallTooltip(event.windowPosition, `一号监测点`)
      })
      graphic.on(mars3d.EventType.mouseOut, (event) => {
        graphic.closeSmallTooltip()
      })
      graphic.on(mars3d.EventType.popupOpen, function (event) {
        console.log(event.container)
        //显示加载
        var loadingDom = event.container.querySelector('.loading')
        loadingDom.style.display = 'flex'
        //前往目标点
        var toCartesian3 = Cesium.Cartesian3.fromDegrees(detail.lng, detail.lat, detail.alt * 1 + 200);
        map.cancelFlyTo().flyToPositions([toCartesian3], {
          duration: 1,
          radius: 500,
          // heading: Math.random() * 360,
          pitch: -70,
          roll: 0,
          complete: () => { }
        })
        //请求获取数据
        setTimeout(() => {
          // event.container.querySelector('#dplayer')
          loadingDom.style.display = 'none'
        }, 2000)
      })
      return graphic;
    },

    //创建告警波纹
    createWarningCircle(params = {}) {
      const warningCicle = new mars3d.graphic.CirclePrimitive({ //圆形动态扩散图
        id: 'warnpoi_' + params.id,
        show: false,
        position: [params.lng, params.lat, params.alt],
        style: {
          clampToGround: params.clampToGround,
          radius: params.radius || 150,
          materialType: mars3d.MaterialType.CircleWave,
          materialOptions: {
            color: "rgba(255,0,0,0.5)",
            count: 2,
            speed: 10
          }
        }
      })
      return warningCicle
    },

    //生成矩阵
    generateModelMatrix(position = [0, 0, 0], rotation = [0, 0, 0], scale = [1, 1, 1]) {
      const rotationX = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(rotation[0])))
      const rotationY = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(rotation[1])))
      const rotationZ = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(rotation[2])))
      if (!(position instanceof Cesium.Cartesian3)) {
        position = Cesium.Cartesian3.fromDegrees(...position)
      }
      const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
      Cesium.Matrix4.multiply(enuMatrix, rotationX, enuMatrix)
      Cesium.Matrix4.multiply(enuMatrix, rotationY, enuMatrix)
      Cesium.Matrix4.multiply(enuMatrix, rotationZ, enuMatrix)
      const scaleMatrix = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(...scale))
      const modelMatrix = Cesium.Matrix4.multiply(enuMatrix, scaleMatrix, new Cesium.Matrix4())
      return modelMatrix
    },

    //编辑树相关
    treeDebugDraw(t) {
      function aaa(index) {
        var treeActive = index;
        drawDebugLayer.unbindContextMenu()
        drawDebugLayer.bindContextMenu([
          {
            text: "开启编辑",
            show: function (e) {
              const graphic = e.graphic
              if (!graphic || !graphic.hasEdit) {
                return false
              }
              return !graphic.isEditing
            },
            callback: (e) => {
              const graphic = e.graphic
              if (!graphic) {
                return false
              }
              if (graphic) {
                drawDebugLayer.startEditing(graphic)
              }
            }
          },
          {
            text: "删除",
            show: (event) => {
              const graphic = event.graphic
              if (!graphic || graphic.isDestroy) {
                return false
              } else {
                return true
              }
            },
            callback: (e) => {
              const graphic = e.graphic
              if (!graphic) {
                return
              }
              const parent = graphic.parent // 右击是编辑点时
              drawDebugLayer.removeGraphic(graphic)
              if (parent) {
                drawDebugLayer.removeGraphic(parent)
              }
            }
          }
        ])
        var scale = 1;
        if (treeActive == 1) {
          scale = 1.8;
        }
        if (treeActive == 2) {
          scale = 1.6;
        }
        if (treeActive == 3) {
          scale = 0.8;
        }
        if (treeActive == 4) {
          scale = 1.4;
        }
        if (treeActive == 5) {
          scale = 1;
        }
        if (treeActive == 6) {
          scale = 2;
        }
        if(index == 'lu'){
          drawDebugLayer.startDraw({
            type: "modelP",
            name: 'lu',
            style: {
              scale: 1,
              // heading: 0,
              // pitch: 0,
              // roll: 0,
              url: basePathUrl + 'models/lu.glb',
            },
            success: (graphic) => {}
          })
        }else{
          drawDebugLayer.startDraw({
            type: "modelP",
            name: 'tree_' + treeActive,
            style: {
              scale,
              heading: Math.random() * 360,
              pitch: 0,
              roll: 0,
              url: basePathUrl + 'models/tree_' + treeActive + '.glb',
            },
            success: (graphic) => {
              aaa(treeActive)
            }
          })
        }
      }
      if (t == 1) {
        //开始放置
        aaa(this.treeActive)
      }
      if (t == 2) {
        //停止放置
        drawDebugLayer.stopDraw()
      }
      if (t == 3) {
        //打印数据
        console.log(drawDebugLayer.toJSON())
      }
      if (t == 'lu') {
        aaa('lu')
      }
    },
    drawDebugLayerStopDraw() {
      drawDebugLayer.stopDraw()
    },
    //绘制面
    async measureSurfaceLength() {
      var measure = new mars3d.thing.Measure({
        label: {
          color: "#ffffff",
          font_family: "楷体",
          font_size: 20,
          background: false
        },
        isAutoEditing: false // 绘制完成后是否自动激活编辑
        // drawEndEventType: mars3d.EventType.rightClick,
        // drawDelEventType: mars3d.EventType.middleClick
      })
      map.addThing(measure)

      measure.on(mars3d.EventType.start, function (e) {
        console.log("开始异步分析")
      })
      measure.on(mars3d.EventType.end, function (e) {
        console.log("完成异步分析", e)
      })
      const graphic = await measure.areaSurface({
        style: {
          color: "rgba(255,255,0,0.1)"
        },
        splitNum: 10, // step插值分割的个数
        exact: false // 是否进行精确计算， 传false时是否快速概略计算方式，该方式计算精度较低，但计算速度快，仅能计算在当前视域内坐标的高度
      })
    },
    //删除缓存
    async clearCache() {
      const e = await navigator?.storage?.estimate();
      let n = (e.usage / 1024 / 1024).toFixed(1);
      if(window.confirm(`本操作将清空站点${n}MB缓存，请确定？`)){
        window.localforage.dropInstance({
          name: "CesiumNetworkPlug",
        }).then(function () {
          window.location.reload()
        });
      }
    },
    /**
     * 框选范围内POI
     */
    async drawPolygon() { //获取范围内POI
      if (drawDebugPolygon) {
        this.removeDrawPolygonAll()
        return;
      }
      drawDebugPolygon = await map.graphicLayer.startDraw({
        type: "polygon",
        style: {
          color: "#ffff00",
          opacity: 0.1,
          clampToGround: true
        },
      })
      this.updateDrawDebugGraphicSelected()
    },
    updateDrawDebugGraphicSelected() { //范围的改变POI为半透明，并回调
      drawDebugGraphicSelected = [];
      mainLayer.eachGraphic((graphic) => {
        const position = graphic.positionShow;
        if ((graphic.name || '').indexOf('poi_') > -1 && position && graphic.show == true) {
          const isInArea = drawDebugPolygon.isInPoly(position)
          if (isInArea) {
            graphic.setStyle({
              opacity: 0.4,
            })
            drawDebugGraphicSelected.push(graphic);
          }
        }
      })
      this.drawDebugCallback()
    },
    removeDrawPolygonAll() {
      if (drawDebugPolygon) {
        drawDebugPolygon.remove()
        drawDebugPolygon = null;
      }
      for (let i = 0; i < drawDebugGraphicSelected.length; i++) {
        const graphic = drawDebugGraphicSelected[i]
        graphic.setStyle({
          opacity: 1,
        })
      };
      drawDebugGraphicSelected = []
    },
    //框选回调-----------------------
    drawDebugCallback() {
      console.log(drawDebugGraphicSelected)
    },



    //请求接口
    async postData(url = "", data = {}) {
      const response = await fetch(url, {
        method: "POST", // *GET, POST, PUT, DELETE, etc.
        mode: "cors", // no-cors, *cors, same-origin
        cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
        credentials: "same-origin", // include, *same-origin, omit
        headers: {
          "Content-Type": "application/json",
          // 'Content-Type': 'application/x-www-form-urlencoded',
        },
        redirect: "follow", // manual, *follow, error
        referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
        body: JSON.stringify(data), // body data type must match "Content-Type" header
      });
      var res = response.json(); // parses JSON response into native JavaScript objects
    },


  }
}
</script>

<style scoped lang="scss">
.map-container {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

#map {
  position: absolute;
  left: 0px;
  top: 0px;
  width: calc(100% + 0px);
  height: calc(100% + 0px);
  z-index: 100;
}

.tree-container {
  display: flex;
  justify-content: flex-start;
  margin-bottom: 15px;

  .tree-item {
    margin-right: 10px;
    cursor: pointer;
    width: 40px;
    height: 40px;
    border: none;
    border-bottom: 5px solid transparent;
    background-size: auto 40px;
    color: #333;

    &.active {
      border-bottom: 5px solid #43a1ff;
    }
  }
}
</style>
